from scipy.stats import t, f
import numpy as np
import math

# 2. Function for Paired t-Test
def paired_t_test(alpha, sides, mean_pre, mean_post, std_diff, power):
    """
    Calculate sample size for a paired t-test, rewritten without reusing the one-sample t-test logic.

    Parameters:
    - alpha: significance level (e.g., 0.05 for 5%)
    - sides: 1 for one-sided test, 2 for two-sided test
    - mean_pre: mean before the intervention
    - mean_post: mean after the intervention
    - std_diff: standard deviation of the paired differences
    - power: desired power (e.g., 85 for 85%)

    Returns:
    - Sample size required for the paired t-test
    """
    n = 2  # Initial sample size
    mean_diff = abs(mean_pre - mean_post)  # Absolute difference between paired means

    while True:
        df = n - 1  # Degrees of freedom
        effect_size = mean_diff / std_diff  # Effect size
        ncp = math.sqrt(n) * effect_size  # Non-centrality parameter

        if sides == 1:  # One-sided test
            t_crit = t.ppf(1 - alpha, df)
            achieved_power = 1 - t.cdf(t_crit, df, ncp)
        elif sides == 2:  # Two-sided test
            t_crit_1 = t.ppf(1 - alpha / 2, df)
            t_crit_2 = t.ppf(alpha / 2, df)
            achieved_power = 1 - t.cdf(t_crit_1, df, ncp) + t.cdf(t_crit_2, df, ncp)

        if achieved_power >= power / 100:
            return math.ceil(n)

        n += 0.01

# Example 2: Paired t-Test
example_2 = paired_t_test(0.05, 2, 28.5, 26.0, 4.5, 85)
print("Example 2:", example_2, "samples needed for Paired t-Test")